#! /your/favourite/path/to/ruby
# -*- coding: utf-8 -*-

# Copyright (c) 2014 Urabe, Shyouhei.  All rights reserved.
#
# Redistribution  and  use  in  source   and  binary  forms,  with  or  without
# modification, are  permitted provided that the following  conditions are met:
#
#     - Redistributions  of source  code must  retain the  above copyright
#       notice, this list of conditions and the following disclaimer.
#
#     - Redistributions in binary form  must reproduce the above copyright
#       notice, this  list of conditions  and the following  disclaimer in
#       the  documentation  and/or   other  materials  provided  with  the
#       distribution.
#
#     - Neither the name of Internet  Society, IETF or IETF Trust, nor the
#       names of specific contributors, may  be used to endorse or promote
#       products derived from this software without specific prior written
#       permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
# AND ANY  EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED  TO, THE
# IMPLIED WARRANTIES  OF MERCHANTABILITY AND  FITNESS FOR A  PARTICULAR PURPOSE
# ARE  DISCLAIMED. IN NO  EVENT SHALL  THE COPYRIGHT  OWNER OR  CONTRIBUTORS BE
# LIABLE  FOR   ANY  DIRECT,  INDIRECT,  INCIDENTAL,   SPECIAL,  EXEMPLARY,  OR
# CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT   NOT  LIMITED  TO,  PROCUREMENT  OF
# SUBSTITUTE  GOODS OR SERVICES;  LOSS OF  USE, DATA,  OR PROFITS;  OR BUSINESS
# INTERRUPTION)  HOWEVER CAUSED  AND ON  ANY  THEORY OF  LIABILITY, WHETHER  IN
# CONTRACT,  STRICT  LIABILITY, OR  TORT  (INCLUDING  NEGLIGENCE OR  OTHERWISE)
# ARISING IN ANY  WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF  ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# The Arrays, as described in RFC7159 section 5.
class RFC7159::Array < RFC7159::Value

	# Parse the AST from parser, and convert into corrsponding values.
	# @param  [::Array] ast    the AST, generated by the parser
	# @return [Array]          evaluated instance
	# @raise  [ArgumentError]  malformed input
	def self.from_ast ast
		type, *ary = *ast
		raise ArgumentError, "not an object: #{ast.inspect}" if type != :array
		ary.map! do |a|
			RFC7159::Value.from_ast a
		end
		new ary
	end

	# fetch the index
	# @param  [Integer] idx  index to obtain
	# @return [Value]        corresponding value
	# @return [nil]          not found / out of bounds
	def [] idx
		@array[idx]
	end

	# iterate over the contents
	# @yield [RFC7159::Value] element
	def each &b
		@array.each(&b)
	end

	# @return [Integer] the count of elements
	def size
		@array.size
	end

	alias length size

	# equality
	# @param  [Array] other  comparison target
	# @return [true]         they are equal
	# @return [false]        otherwise.
	def == other
		return false unless length == other.length
		@array.each_index do |i|
			j = @array[i]
			k =  other[i]
			return false unless j == k
		end
		return true
	end

	# @return [::Array] converted array
	def plain_old_ruby_object
		@array.map do |i|
			i.plain_old_ruby_object
		end
	end

	alias to_a   plain_old_ruby_object
	alias to_ary plain_old_ruby_object

	# JSON gem compat
	# @return [::String] JSONified representation
	def to_json
		RFC7159::Dumper.new.dump self
	end

	# @return [::String] the array in string
	def inspect
		sprintf "#<%p:%#016x %p>", self.class, self.object_id << 1, @array
	end

	# For pretty print
	# @param [PP] pp the pp
	def pretty_print pp
		hdr = sprintf '#<%p:%#016x', self.class, self.object_id << 1
		pp.group 1, hdr, '>' do
			pp.text ' '
			RFC7159::Dumper.kandr pp, 1, @array.each, '[', ']' do |i|
				i.pretty_print pp
			end
		end
	end

	private
	private_class_method:new
	# @private
	def initialize ary
		@array = ary
		@array.freeze
	end
end

# 
# Local Variables:
# mode: ruby
# coding: utf-8-unix
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# fill-column: 79
# default-justification: full
# End:
